package IOSreamAndFile;

import java.io.*;

/*(输入)     BufferedReader
* Reader     FileReader
*            FilterReader
*            ...
*
*
*(输出)      BufferedWriter
* Writer     FileWriter
*            FilterWriter
*            ...
* */
public class characterStream {
    public static void main(String[] args) {
    /*
    字符流：以字符为单位，读写数据的流

   FileWriter类构造方法：
   //根据提供的文件路径构建一条文件输出通道
   public FileWriter(String fileName) throws IOException;
   //根据提供的文件路径构建一条文件输出通道，并根据append的值决定是将内容追加到末尾还是直接覆盖
   public FileWriter(String fileName, boolean append) throws IOException;
   //根据提供的文件信息构建一条文件输出通道
   public FileWriter(File file) throws IOException;
   //根据提供的文件信息构建一条文件输出通道，并根据append的值决定是将内容追加到末尾还是直接覆盖
   public FileWriter(File file, boolean append) throws IOException;


   //Writer类的方法：
   public void write(int c) throws IOException; //写一个字符
   public void write(char cbuf[]) throws IOException;//将给定的字符数组内容写入到文件中
   //将给定的字符数组中给定偏移量和长度的内容写入到文件中
   abstract public void write(char cbuf[], int off, int len) throwsIOException;
   public void write(String str) throws IOException;//将字符串写入到文件中
   abstract public void flush() throws IOException;//强制将通道中的数据全部写出
   abstract public void close() throws IOException;//关闭通道
     */

    //将"\n我草了呀！"写入到io.txt文件中
        try(FileWriter fw = new FileWriter("selfStudy\\heiMa\\middleGrammar\\src\\IOSreamAndFile\\io.txt",true)) {
           String text = "\n我草了了呀！";
           char [] data = text.toCharArray();
           //一次写一个字符
           //for(char c:data) fw.write(c);
           //一次写一个字符数组
           //fw.write(data);
           //一次写一个字符数组的一部分
           //fw.write(data, 1, data.length - 1);//偏移一个字符
           //一次写一个字符串(太好用了)
           //fw.write(text);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }



        /*
        FileReader类构造方法：
        //根据提供的文件路径构建一条文件输入通道
        public FileReader(String fileName) throws FileNotFoundException;
        //根据提供的文件信息构建一条文件输入通道
        public FileReader(File file) throws FileNotFoundException;

        Reader类的方法：
        public int read() throws IOException; //读取一个字符
        public int read(char cbuf[]) throws IOException; //读取字符到给定的字符数组中
        //将读取的字符按照给定的偏移量和长度存储在字符数组中
        abstract public int read(char cbuf[], int off, int len) throws IOException;
        abstract public void close() throws IOException;//关闭通道
         */
      //将"io.txt"文件中的内容读取到控制台中
        try(FileReader fr = new FileReader("selfStudy\\heiMa\\middleGrammar\\src\\IOSreamAndFile\\io.txt")) {
            //一次读一个字符
//            StringBuilder builder = new StringBuilder();
//            while (true){
//            int c = reader.read();
//            if(c == -1) break;
//            builder.append((char)c);
//            }
//            System.out.println(builder);

            char[] buffer = new char[4096];
            int offset = 0;
            while (true){
             // int len = reader.read(buffer);//一次读一个字符数组
                int len = fr.read(buffer, offset, 30);//一次读一个字符数组的一部分
                if(len == -1) break;
                offset += len;
            }
            System.out.println(new String(buffer, 0, offset));

        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }


        //用字符流复制文件
        String sourcePath = "selfStudy\\heiMa\\middleGrammar\\src\\IOSreamAndFile\\io.txt";
        String targetPath = "selfStudy\\heiMa\\middleGrammar\\src\\IOSreamAndFile\\ioCopy.txt";
        copyFile(sourcePath, targetPath);
    }//main方法结束

    public static void copyFile(String sourceFile, String destFile) {
        File file = new File(destFile);
        File parent = file.getParentFile();
        if (!parent.exists()) parent.mkdirs();
        try (Reader reader = new FileReader(sourceFile);
             Writer writer = new FileWriter(file, false)) {
            char[] buffer = new char[4096];
            while (true) {
                int len = reader.read(buffer);
                if (len == -1) break;
                writer.write(buffer, 0, len);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}//class结束


class bufferCharacterStream{
    public static void main(String[] args) {
       /*
       跟字节缓冲流一样的底层，这个就看看方法吧

       BufferedWriter类构造方法：
       //根据给定的字符输出流创建一个缓冲字符输出流，缓冲区大小使用默认大小
       public BufferedWriter(Writer out);
       //根据给定的字符输出流创建一个缓冲字符输出流，并指定缓冲区大小
       public BufferedWriter(Writer out, int size);

       BufferedWriter类构造方法：
       //根据给定的字符输入流创建一个缓冲字符输入流，缓冲区大小使用默认大小
       public BufferedReader(Reader in);
       //根据给定的字符输入流创建一个缓冲字符输入流，并指定缓冲区大小
       public BufferedReader(Reader in, int size);
      */

        //使用缓冲流复制文件
        String sourcePath = "selfStudy\\heiMa\\middleGrammar\\src\\IOSreamAndFile\\io.txt";
        String targetPath = "selfStudy\\heiMa\\middleGrammar\\src\\IOSreamAndFile\\ioCopy.txt";
        copyFile(sourcePath, targetPath);
    }
    public static void copyFile(String sourcePath, String targetPath) {
        File file = new File(targetPath);
        File parentFile = file.getParentFile();
        if (!parentFile.exists()) parentFile.mkdirs();
        //注意：他们的构造时候需要传入的是字符流对象，而不是文件对象
        try (BufferedReader br = new BufferedReader(new FileReader(sourcePath));
             BufferedWriter bw = new BufferedWriter(new FileWriter(targetPath, false))) {
            char[] buffer = new char[4096];
            while (true){
                int len = br.read(buffer);
                if(len == -1) break;
                bw.write(buffer, 0, len);
            }
            bw.flush();//防止最后一次写入数据，缓冲区没有满，导致最后一次写入数据没有与磁盘交互
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}